
import requests
import re

from tools.handle_loging import my_logger
from tools.handle_attribute import HandleAttribute
from tools.handle_ini import conf
from tools.handle_sign import HandleSign

class SendRequest:
    def __init__(self):
        self.headers = {"X-Lemonban-Media-Type": "lemonban.v3", "Content-Type": "application/json"}

    def __handle_url(self,url):
        # http://api.lemonban.com/futureloan/member/#member_id#/info
        base_url = conf.get(section="host",option="domain")
        if url.startswith("http://") or url.startswith("https://"):
            request_url = url
        else:
            request_url = base_url + url
        new_url = self.__handle_replace_url(url=request_url)
        return new_url

    def __handle_replace_url(self,url):
        re_str = "#(\w.+?)#"
        # ["member_id_1","member_id_2"]
        key_list = re.findall(re_str,url)
        if len(key_list) >=1:
            for key in key_list:
                if hasattr(HandleAttribute,key):
                    url = url.replace(f"#{key}#",str(getattr(HandleAttribute,key)))
                else:
                    my_logger.info(msg="url中需要替换的key属性不存在")
            return url
        else:
            return url


    def __handle_headers(self):
        # token 是按照提取规则，从登陆响应结果提取出来，然后设置成HandleAttribute类的类属性
        # 如果HandleAttribute类有token属性，那么就讲token设置到请求头当中
        if hasattr(HandleAttribute,"token"):
            self.headers["Authorization"] = "Bearer {}".format(getattr(HandleAttribute,"token"))
        else:
            pass

    def __handle_media_type(self,request_data):
        # 判断请求头X-Lemonban-Media-Type 是否是v3版本，是V3版本才需要去加密处理
        if self.headers["X-Lemonban-Media-Type"] == "lemonban.v3":
            # 需要加密处理
            if hasattr(HandleAttribute,"token"):
                token = getattr(HandleAttribute,"token")
                sign_data = HandleSign.generate_sign(token=token)
                request_data.update(sign_data)
        else:
            # token鉴权，不需要加密处理
            my_logger.info(msg="其他鉴权方式，请求参数无需处理")
        return request_data

    def send_request(self,method,url,data):
        """
        :param method: 请求方法
        :param url: 请求地址
        :param data: 请求参数
        :param token: 鉴权token
        :return: 返回接口响应结果
        """
        try:
            my_logger.info(msg='========开始发起请求========')
            my_logger.info(msg='请求方式:\n{}'.format(method))
            my_logger.info(msg='请求地址:\n{}'.format(url))
            my_logger.info(msg='请求参数：\n{}'.format(data))
            new_method = method.upper()
            new_url = self.__handle_url(url=url)  # 请求地址拼接，参数替换
            self.__handle_headers()  # 请求头处理
            new_data = self.__handle_media_type(request_data = data) # v3版本鉴权处理
            if new_method == 'GET':
                response = requests.get(url=new_url,params=new_data,headers = self.headers)
                my_logger.info(msg='GET请求返回:\n{}'.format(response.json()))
                return response.json()
            elif new_method == 'POST':
                response = requests.post(url=new_url, json=new_data, headers=self.headers)
                my_logger.info(msg='POST请求返回:\n{}'.format(response.json()))
                return response.json()
            elif new_method == 'PATCH':
                response = requests.patch(url=new_url, json=new_data, headers=self.headers)
                my_logger.info(msg='patch请求返回:\n{}'.format(response.json()))
                return response.json()
            else:
                my_logger.info(msg='{}请求类型暂不支持,后续再加'.format(method))
                raise AssertionError
        except Exception as e:
            my_logger.error(msg='========请求发送结束，请求报错了========')
            my_logger.exception(e)
            raise